package main

import (
	"background/config"
	"background/controller"
	"background/controller/middle"
	"background/db"
	_ "background/docs"
	"background/logs"
	"background/model"
	"log"
	"strconv"

	"github.com/gin-gonic/gin"
	ginSwagger "github.com/swaggo/gin-swagger" // gin-swagger middleware
	"github.com/swaggo/gin-swagger/swaggerFiles"
	sessions "github.com/tommy351/gin-sessions"
)

// @title 大厅功能api
// @version 1.0
// @host localhost:8080
// @BasePath /api/v1

var (
	userController    = controller.UserController{}
	mailContoller     = controller.MailController{}
	fileController    = controller.FileController{}
	planController    = controller.PlanController{}
	openapiController = controller.OpenApiController{}
)

func CORSMiddleware(c *gin.Context) {
	c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
	if config.ApiConfig().RunMode == "release" {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:8081")
	} else {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "https://testingcloud.club")
	}
	c.Writer.Header().Set("Access-Control-Max-Age", "86400")
	c.Writer.Header().Set("Access-Control-Allow-Headers",
		"X-Requested-With,"+
			" Content-Type, Origin, Authorization,"+
			"Accept,Client-Security-Token, Accept-Encoding,"+
			"x-access-token,Access-Control-Request-Method,"+
			"Access-Control-Request-Headers")
	c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
	c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

	log.Print("remote addr is ", c.Request.RemoteAddr)

	if c.Request.Method == "OPTIONS" {
		log.Println("OPTIONS")
		c.AbortWithStatus(200)
	} else {
		c.Next()
	}
}

func InitConfig() {
	e := config.Init("user.yaml")
	if nil != e {
		log.Println(e.Error())
	}
}

func InitMysql() {
	c := config.GetMysqlConfig()
	if c == nil {
		logs.Error("cannnot connect mysql server")
	} else {
		db.Init()
	}
}

func InitRedisConfig() {
	e := config.InitRedis()
	if nil != e {
		logs.Error(e.Error())
		return
	}
}

func InitElasticSearch() {
	e := db.GetElastic().CreateIndex("hardware", model.HardwareTypeMapping())
	if nil != e {

	}
}

func InitLogs() {
	logs.Init(config.GetLogConfig().Dir, config.GetLogConfig().File, config.GetLogConfig().Level, config.GetLogConfig().SaveFile)
}

func main() {
	InitConfig()
	InitLogs()
	InitRedisConfig()
	InitMysql()
	db.InitELK()

	r := gin.Default()
	store := sessions.NewCookieStore([]byte("secret123"))
	r.Use(sessions.Middleware("sess_store", store))
	r.Use(CORSMiddleware) // Cross domain

	// go func() {
	// 	server := network.ServerFactory("0.0.0.0", config.ApiConfig().WsServerConf)
	// 	server.SetHandle(WsHandle{})
	// 	e := server.Run()
	// 	if nil != e {
	// 	}
	// }()

	go func() {

		// programatically set swagger info
		r := gin.New()
		// use ginSwagger middleware to serve the API docs
		r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
		r.Run(":9992")
	}()
	api := r.Group("/api")
	{
		/** 添加或修改用户 **/
		api.POST("/user", userController.SetUser)
		/** 删除用户 **/
		api.DELETE("/user", userController.DelUser)
		/** 获取单独用户详情信息 methods(id) **/
		api.GET("/user", middle.AuthMiddle, userController.GetUser)
		/** 获取所有用户 **/
		api.GET("/users", middle.AuthMiddle, userController.Users)
		api.POST("/search_users", middle.AuthMiddle, userController.SerarchUsers)
		/** 用户登录 **/
		api.POST("/login", userController.Login)
		/** 用户注册 **/
		api.POST("/register", userController.Register)
		/** 用户退出登陆 **/
		api.GET("/logout/:token", userController.Logout)
		api.POST("/verify", mailContoller.OnSendEmailCode)
		/** 修改密码**/
		api.POST("modify_pass", middle.AuthMiddle, userController.ModifyPasswd)

		api.GET("/article/:id", controller.GetArticle)        //获取文章
		api.POST("/articles", controller.GetArticles)         // 获取所有文章
		api.GET("/articles_tree", controller.GetArticlesTree) // 获取所有文章

		api.PUT("/article_tree", controller.AddArticleTree)            // 添加文章
		api.PUT("/knowledge", controller.AddKnowledge)                 // 添加文章
		api.PUT("/article_tree_history", controller.AddArticleHistory) // 添加文章

		api.PUT("/article_search", controller.SearchArticles)                          // 添加文章
		api.GET("/article_type", controller.ArticlesType)                              //获取所有文章分类
		api.PUT("/article_type", controller.AddArticleType)                            // 添加文章分类
		api.DELETE("/article_type", controller.DeleteArticleType)                      // 删除文章分类
		api.POST("/doc_search_term", controller.SearchArticleES)                       // 文章内容搜索,基于es的倒排
		api.POST("/doc_match_search_hightlight", controller.SearchArticleESHightLight) // 文章内容搜索,基于es的倒排

		api.POST("/article_update", controller.UpdateArtilce)          //更新文章
		api.POST("/article_update_tree", controller.UpdateArtilceTree) //更新文章

		api.GET("/articleCount", controller.GetArticleCount)          //获取所有文章个数
		api.DELETE("/article/:id", controller.DeleteArticle)          ////删除文章
		api.DELETE("/article_tree/:id", controller.DeleteArticleTree) ////删除文章
		api.GET("/article_history", controller.GetArticleHistory)     // 历史

		api.POST("/download_pic", fileController.OnUpaloadPic)          // 获取类所在的组
		api.POST("/image_upload", fileController.OnUpload)              //  上传图片，如果图片太大自动裁减为原来的一半
		api.POST("/image_upload_origin", fileController.OnUploadOrigin) //  上传图片
		api.GET("/image_download/:file", fileController.OnDownLoad)     // 下载图片
		api.GET("/image_thumbnail/:file", fileController.OnThumbnail)   // 下载图片
		api.GET("/doc_types", controller.ArticlesTypes)                 // 获取所有的文章类型
		api.POST("/hardware", controller.AddHardware)                   // 新增硬件
		api.GET("/hardware", controller.ReadHardWare)                   // 读取硬件
		api.DELETE("/hardware", controller.DeleteHardWare)              // 读取硬件

		api.POST("/upload_doc", fileController.OnFileUploadFileMarkdown) // 上传文件

		api.PUT("/file", fileController.OnFileUploadFile) // 上传文件
		api.GET("/file", fileController.DownloadFile)     // 下载 文件
		api.GET("/filelist", fileController.FileList)     // 文件列表
		api.GET("/fileType", fileController.FileType)     // 文件类型

		api.PUT("/memo", controller.CreateMemo)      // 备忘录新建
		api.POST("/memo", controller.UpdateMemo)     // 备忘录更新
		api.POST("/memos", controller.GetMemos)      // 备忘录批量
		api.POST("/delmemo", controller.DeleteMemos) //删除备忘录
		api.GET("/memo", controller.GetMemo)         // 单独读取备忘录
		api.GET("/memocnt", controller.GetMemoCnt)   // 单独读取备忘录

		api.GET("doc_groups", controller.GetDocGroup)      // 获取所有的文章分组
		api.POST("type_group", controller.GetDocTypeGroup) // 获取类所在的组
		api.POST("group_type", controller.GetDoGroupcType) // 获取类所在的组

		api.GET("doc_versions", nil) // 获取文章的某个版本

		api.PUT("/book", controller.CreateBook)       //新建书籍
		api.POST("/book", controller.UpdateBook)      // 更新书籍
		api.POST("/getbook", controller.GetBook)      // 单书籍数据
		api.POST("/getbooks", controller.GetPageBook) // 批量书籍
		api.POST("/delbook", controller.Delbook)      // 删除书籍
		api.GET("/bookcount", controller.BookCount)   // 书籍名称

		api.POST("/get_plans", planController.GetPlanDates) // 获取当天的所有计划
		api.PUT("/plan", planController.AddPlan)            // 添加计划
		api.DELETE("/plan", planController.DelPlan)         // 删除计划
		api.POST("/plan_days", planController.PlanDay)      // 获取本月有计划天数
		api.GET("/plan_types", planController.Types)

		api.PUT("/undo", planController.CreateUndo)                 // 新增待办事项
		api.POST("/undo", planController.UpdateUndo)                // 更新待办事项
		api.POST("/undo_finish/:id", planController.FinishUndo)     // 完成待办事项
		api.POST("/undo_unfinish/:id", planController.UnFinishUndo) // 已完成事项改未完成
		api.GET("/undo", planController.GetUndo)                    // 获得待办事项
		api.GET("/done", planController.GetDone)                    // 获得待办事项

		api.DELETE("/undo/:id", planController.DeleteUndo) // 删除待办事项

		api.PUT("/doc_template", controller.CreateDocTemplate)        // 创建文章模板
		api.POST("/doc_template", controller.UpdateDocTemplate)       // 更新文章模板
		api.POST("/get_doc_template", controller.GetDocTemplate)      // 获得文章模板
		api.DELETE("/doc_template/:id", controller.DeleteDocTemplate) // 删除文章模板
		api.GET("/doc_template/:id", controller.GetDocTemplateId)     //获得单个文章模板信息
	}

	openapi := r.Group("openapi")
	{
		openapi.POST("/diff")                                            // 比较两个文档差异
		openapi.POST("/ddl2orm", openapiController.DDL2ORM)              // sql ddl转gorm 结构体
		openapi.POST("/ddl2markdown", openapiController.DDL2Markdown)    // sql ddl转markdown 文档
		openapi.POST("/ui2css", openapiController.UI2CSS)                // qt ui文件转css文档
		openapi.POST("/duilib_xml2cpp", openapiController.DuilibXml2Cpp) // duilib to cpp
	}
	e := r.Run(":" + strconv.Itoa(config.GetPort()))
	if nil != e {
		log.Print(e.Error())
	}
}
